'''
Miscellaneous helper functions.
'''

import inspect
from datetime import datetime


def get_subclasses(module, base, with_base=False):
    '''
    Get all classes residing in a given module which subclass a given base class.

    @param with_base Whether to include the base class also
    '''
    subclasses = []
    for name, cls in inspect.getmembers(module):
        if inspect.isclass(cls) and issubclass(cls, base):
            if not with_base and cls is base:
                continue
            subclasses.append(cls)
    return subclasses


def split_cslist(cslist):
    '''
    Split a comma separated list by both newlines and commas.
    '''
    items = []
    for line in cslist.splitlines():
        for item in line.split(','):
            item.strip() and items.append(item.strip())
    return items


def current_timestamp():
    return datetime.utcnow()


def settings_from_prefix(settings, prefix):
    '''
    Return a dictionary of settings all containing the same key prefix, with the
    prefix removed from the keys.
    '''
    data = {}
    for key in settings:
        if key.startswith(prefix):
            data[key.replace(prefix, '')] = settings[key]
    return data


class Storage(dict):
    '''
    Generic container class.
    '''

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError as e:
            raise AttributeError(e)

    def __setattr__(self, key, value):
        self[key] = value

    def __delattr__(self, key):
        try:
            del self[key]
        except KeyError as e:
            raise AttributeError(e)